/**
 * Desenvolvido pela Fábrica de Software do CESUPA.
 * Todos os direitos reservados.
 */
package br.cesupa.fabsoft.nomedoprojeto.system.application.beans;

import br.cesupa.fabsoft.nomedoprojeto.system.application.facades.ApplicationFacade;
import br.cesupa.fabsoft.nomedoprojeto.system.application.facades.appmessages.ApplicationStatusParameterContext;
import br.cesupa.fabsoft.nomedoprojeto.system.infra.view.Message;
import br.cesupa.fabsoft.nomedoprojeto.system.infra.view.MessageFactory;
import br.cesupa.fabsoft.nomedoprojeto.system.infra.view.MessageType;
import java.util.Map;
import javax.faces.context.FacesContext;

/**
 * Bean used to control application status messages.
 *
 * @author Breno Leite
 */
public class ApplicationStatusBean {

    /**
     * Message status of the last operation executed in the system.
     */
    private Message currentMessage = null;
    /**
     * If the message should be rendered or not.
     */
    private boolean currentMessageActive = false;

    /**
     * Close the message display on the user interface.
     *
     * @return a string based navigation stimulus for the controller
     */
    public String closeMessage() {
        setCurrentMessageActive(false);
        return null;
    }

    /**
     * Retrieves the current instance of this bean been managed by the Java
     * Server Faces.
     *
     * @return the current instance of this bean
     */
    public static ApplicationStatusBean getCurrentInstance() {
        return (ApplicationStatusBean) ApplicationFacade.getManagedBeanFacade().
                getManagedBeanCurrentInstance("applicationStatusBean");
    }

    /**
     * Display a message on the application user interface.
     *
     * @param applicationMessage the {@link Message} to display
     */
    public ApplicationStatusParameterContext displayStatusMessage(final Message message) {
        this.currentMessage = message;
        setCurrentMessageActive(true);
        return new ApplicationStatusParameterContext();
    }

    /**
     * Display a simple <b>info</b> message on the application user interface.
     *
     * @param text the message's text
     * @return a parameter filling context
     */
    public ApplicationStatusParameterContext displayStatusMessage(final String text) {
        displayStatusMessage(new Message(text, MessageType.INFO));
        return new ApplicationStatusParameterContext();
    }

    /**
     * Display a simple message on the application user interface.
     * 
     * @param text the message's text
     * @param messageType the message's type
     * @return a parameter filling context
     */
    public ApplicationStatusParameterContext displayStatusMessage(final String text,
            final MessageType messageType) {
        displayStatusMessage(new Message(text, messageType));
        return new ApplicationStatusParameterContext();
    }

    /**
     * Displays a message present on the application resource bundle.
     *
     * @param messageKey the key of the message present in the resource bundle
     * @param messageType the type to be applied to the message
     * @return a parameter filling context
     */
    public ApplicationStatusParameterContext displayInternationalizedStatusMessage(
            final String messageKey, final MessageType messageType) {
        displayStatusMessage(new MessageFactory().createMessage(messageKey, messageType));
        return new ApplicationStatusParameterContext();
    }

    /**
     * Checks the current HTTP Session for messages which could be originated
     * from non-JSF scope.
     */
    private void checkHTTPSession() {
        Map<String, Object> session =
                FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
        if (session.containsKey("applicationStatusMessage")) {
            Message message = (Message) session.get("applicationStatusMessage");
            displayStatusMessage(message);
            session.remove("applicationStatusMessage");
        }
    }

    /**
     * Returns the application message to display on the user interface. Checks
     * the local variable <code>applicationMessage</code>
     * (setted through <code>displayMessage</code> methods) and the current
     * HTTP session map for defined messages.
     *
     * @return the current message
     */
    public Message getCurrentMessage() {
        checkHTTPSession();
        return currentMessage;
    }

    /**
     * @return the currentMessageActive
     */
    public boolean isCurrentMessageActive() {
        return currentMessageActive;
    }

    /**
     * @param currentMessageActive the currentMessageActive to set
     */
    public void setCurrentMessageActive(final boolean currentMessageActive) {
        this.currentMessageActive = currentMessageActive;
    }
}
